import { useEffect, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import {
  Select,
  Dropdown,
  Button,
  Image,
  Modal,
  message,
  Input,
  Pagination,
  Upload,
} from 'antd'
const { Dragger } = Upload
import type { MenuProps, UploadProps } from 'antd'
import {
  SettingOutlined,
  UploadOutlined,
  CopyOutlined,
  DownloadOutlined,
  HistoryOutlined,
  PictureFilled,
  InboxOutlined,
  DeleteFilled,
} from '@ant-design/icons'
import Masonry from 'react-masonry-css'
import styles from './index.module.less'
import {
  createGroupApi,
  updateGroupApi,
  deleteGroupApi,
  getGroupApi,
  getGroupImagesApi,
  deleteImageApi,
} from '@/request/api/group'
import { uploadImageListApi } from '@/request/api/upload'
import LoadingClass from '@/utils/utilClass/Loading'
import { fetchOriginFile } from '@/utils/func'
import { sourceUrl } from '@/config'

//
//
export default function Home() {
  const navigate = useNavigate()

  // 组选项
  const [groupOptions, setGroupOptions] = useState<any[]>([
    { value: '', label: '全部' },
  ])
  // 当前下拉框选项值
  const [currentGroupId, setCurrentGroupId] = useState<string>('')

  useEffect(() => {
    getGroup()
  }, [])

  // 下拉框选项值变化时
  const onChange = (value: string) => setCurrentGroupId(value)

  // 获取组
  const getGroup = async () => {
    const res = await getGroupApi()
    if (res.code !== 200) return message.error('获取组失败!')
    const arr = res.data.map((item) => {
      return { value: item.id, label: item.name }
    })
    setGroupOptions([{ value: '', label: '全部' }, ...arr])
  }

  const [page, setPage] = useState<number>(1)
  const [pageSize, setPageSize] = useState<number>(15)
  const [total, setTotal] = useState<number>(0)
  // 当前展现的图片
  const [currentImageList, setCurrentImageList] = useState<groupImagesItf[]>([])

  // 分页获取组中的图片
  const getGroupImages = async () => {
    const res = await getGroupImagesApi(currentGroupId, page, pageSize)
    if (res.code !== 200) return message.error('分页获取图片失败！')
    setTotal(res.data.total)
    setCurrentImageList(res.data.list)
  }

  useEffect(() => {
    getGroupImages()
  }, [page, pageSize])

  useEffect(() => {
    setPage(1)
    setPageSize(15)
    getGroupImages()
  }, [currentGroupId])

  // 将下拉项选项过滤
  const filterOption = (
    input: string,
    option?: { label: string; value: string }
  ) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())

  //
  // 下拉菜单项格式处理函数
  const menuHandler = (): MenuProps['items'] => {
    const itemList = [
      { id: 2, label: '修改此组信息', func: () => setUpdateModal(true) },
      { id: 3, label: '删除此组', func: () => setDeleteModal(true) },
      { id: 1, label: '创建新组', func: () => setCreateModal(true) },
      { id: 4, label: '进入回收站', func: () => navigate('/recycle') },
    ]

    const arr = itemList.map((item) => {
      const el = <div onClick={item.func}>{item.label}</div>
      return { key: item.id, label: el }
    })

    return arr
  }

  const classLoading = new LoadingClass()

  const [createModal, setCreateModal] = useState<boolean>(false)
  const [updateModal, setUpdateModal] = useState<boolean>(false)
  const [deleteModal, setDeleteModal] = useState<boolean>(false)
  const [groupInput, setGroupInput] = useState<string>('')

  // 创建新组
  const createGroup = async () => {
    if (groupInput === '') return message.warning('请输入组名！')
    const res = await classLoading._operationFunc(() =>
      createGroupApi(groupInput)
    )
    if (res.code !== 200) return message.error('创建失败！')
    message.success('创建成功！')
    setGroupInput('')
  }

  // 修改组名
  const updateGroup = async () => {
    if (currentGroupId === '') return message.warning('默认组不能修改！')
    if (groupInput === '') return message.warning('请输入组名！')
    const res = await classLoading._operationFunc(() =>
      updateGroupApi(currentGroupId, groupInput)
    )
    if (res.code !== 200) return message.error('修改失败！')
    message.success('修改成功！')
    setGroupInput('')
    getGroup()
  }

  // 删除组
  const deleteGroup = async () => {
    if (currentGroupId === '') return message.warning('默认组不能删除！')
    const res = await classLoading._operationFunc(() =>
      deleteGroupApi(currentGroupId)
    )
    if (res.code !== 200) return message.error('删除失败！')
    message.success('删除成功！')
    getGroup()
    setCurrentGroupId('')
    setDeleteModal(false)
  }

  const [uploadModal, setUploadModal] = useState<boolean>(false)
  // 批量上传的图片列表
  const [imageList, setImageList] = useState<any[]>([])
  // 上传文件组件 ref
  const draggerRef = useRef<any>(null)
  // 已经上传的文件列表
  const [fileList, setFileList] = useState<any[]>([])

  // 批量上传文件 props
  const draggerProps: UploadProps = {
    multiple: true,
    maxCount: 15,
    fileList: fileList, // 已经上传的文件列表（受控）
    onChange(info) {
      setFileList(info.fileList)
      const arr = info.fileList.map((item) => {
        return fetchOriginFile(item.originFileObj)
      })
      setImageList([...arr])
    },
    beforeUpload: () => false,
  }

  // 批量上传图片
  const uploadImageList = async () => {
    if (imageList.length === 0) return message.warning('图片列表为空！')

    let formdata = new FormData()
    imageList.reduce((accumulator, item) => {
      accumulator.append('images', item)
      return accumulator // 返回累加器
    }, formdata)

    const res = await classLoading._operationFunc(() =>
      uploadImageListApi(currentGroupId, formdata)
    )
    if (res.code !== 200) return message.error('上传图片失败！')
    message.success('上传图片成功！')
    setImageList([])
    setFileList([])
    draggerRef.current.fileList = []
    getGroupImages()
  }

  return (
    <div className={styles.homeContainer}>
      {/* 操作栏 */}
      <div className={styles.bar}>
        <div className={styles.label}>范围：</div>
        <Select
          style={{ width: '160px' }}
          showSearch
          placeholder="Select a person"
          value={currentGroupId}
          onChange={onChange}
          optionFilterProp="label"
          filterOption={filterOption}
          options={groupOptions}
          onDropdownVisibleChange={(visible) => (visible ? getGroup() : '')}
        />

        <Dropdown
          trigger={['hover']}
          menu={{ items: menuHandler() }}
          arrow
          placement="bottomRight"
        >
          <div
            style={{ padding: '0px 24px' }}
            onClick={(e) => e.preventDefault()}
          >
            <SettingOutlined
              title="设置"
              style={{
                fontSize: '22px',
                cursor: 'pointer',
                color: '#6a6a6a',
              }}
            />
          </div>
        </Dropdown>

        <Button
          title="上传图片到此组"
          type="primary"
          icon={<UploadOutlined />}
          onClick={() => setUploadModal(true)}
        ></Button>
      </div>

      {/* 分页栏 */}
      <PaginationBar
        page={page}
        pageSize={pageSize}
        total={total}
        setPage={setPage}
        setPageSize={setPageSize}
      />

      {/* 图片列表 */}
      <div className={styles.imageList}>
        <Masonry
          breakpointCols={{
            default: 3,
            450: 3,
            560: 4,
            670: 5,
            780: 6,
            890: 7,
          }}
          className="my_masonry_grid"
          style={{ display: 'flex' }}
        >
          {currentImageList.map((item, index) => (
            <ImageItem
              key={item.id}
              id={item.id}
              path={sourceUrl + item.path}
              time={item.upload_time}
              serial={index}
              refreshList={getGroupImages}
            />
          ))}
        </Masonry>
      </div>

      {/* 创建新组对话框 */}
      <Modal
        open={createModal}
        onCancel={() => setCreateModal(false)}
        footer={null}
      >
        <Input
          value={groupInput}
          onChange={(event) => setGroupInput(event.target.value.trim())}
          style={{ width: '90%', marginRight: '20px', marginBottom: '10px' }}
        />
        <Button
          type="primary"
          loading={classLoading._loading}
          onClick={createGroup}
        >
          创建新组
        </Button>
      </Modal>

      {/* 修改组名对话框 */}
      <Modal
        open={updateModal}
        onCancel={() => setUpdateModal(false)}
        footer={null}
      >
        <Input
          value={groupInput}
          onChange={(event) => setGroupInput(event.target.value.trim())}
          style={{ width: '90%', marginRight: '20px', marginBottom: '10px' }}
        />
        <Button
          type="primary"
          loading={classLoading._loading}
          onClick={updateGroup}
        >
          修改当前组名
        </Button>
      </Modal>

      {/* 删除当前组对话框 */}
      <Modal
        open={deleteModal}
        onCancel={() => setDeleteModal(false)}
        footer={null}
      >
        <Button
          type="primary"
          loading={classLoading._loading}
          onClick={deleteGroup}
          danger
        >
          确定删除当前组？
        </Button>
      </Modal>

      {/* 上传图片对话框 */}
      <Modal
        title="上传图片"
        open={uploadModal}
        onCancel={() => setUploadModal(false)}
        footer={null}
      >
        <Dragger {...draggerProps} ref={draggerRef}>
          <p className="ant-upload-drag-icon">
            <InboxOutlined />
          </p>

          <p className="ant-upload-text">点击或拖动文件到此区域进行上传。</p>
          <p className="ant-upload-hint">
            支持单个或批量上传。严禁上传公司数据或其他禁止的文件。
          </p>
          <p className="ant-upload-text">Max: 15</p>
        </Dragger>
        <div
          style={{
            display: 'flex',
            justifyContent: 'center',
            marginTop: '16px',
          }}
        >
          <Button
            type="primary"
            loading={classLoading._loading}
            onClick={uploadImageList}
          >
            确认上传
          </Button>
        </div>
      </Modal>
    </div>
  )
}

//
// 分页栏
function PaginationBar({
  page = 1,
  pageSize = 15,
  setPage = () => '',
  setPageSize = () => '',
  total = 0,
}: {
  page: number
  pageSize: number
  total: number
  setPage: Function
  setPageSize: Function
}) {
  const paginationRef = useRef<HTMLDivElement>()

  useEffect(() => {
    const box = paginationRef.current
    let barNode: HTMLDivElement
    let optionsNode: HTMLDivElement

    barNode = box?.querySelector('.ant-pagination')
    optionsNode = box?.querySelector('.ant-pagination-options')

    if (barNode) {
      barNode.style.display = 'flex'
      barNode.style.alignItems = 'center'
    }
    if (optionsNode) {
      optionsNode.style.display = 'inline-block'
      optionsNode.style.marginLeft = '8px'
    }
  }, [])

  const onChangeHandler = (page: number, size: number) => {
    setPage(page)
    setPageSize(size)
  }

  return (
    <div className={styles.PaginationBar} ref={paginationRef}>
      <PictureFilled
        title={`图片总数：${total}`}
        style={{
          fontSize: '26px',
          fontWeight: 'bold',
          color: '#6a6a6a',
          cursor: 'pointer',
        }}
      />

      <Pagination
        simple
        defaultCurrent={page}
        current={page}
        pageSize={pageSize}
        total={total}
        showSizeChanger={true}
        onChange={onChangeHandler}
      />
    </div>
  )
}

//
// 图片项
function ImageItem({
  id = '',
  path = '',
  time = '',
  serial = 0,
  refreshList = () => '',
}: {
  id: string
  path: string
  time: string
  serial: number
  refreshList: Function
}) {
  const myElementRef = useRef<HTMLDivElement>()
  const [show, setShow] = useState<boolean>(false)

  useEffect(() => {
    const element = myElementRef.current
    element.addEventListener('mouseenter', () => {
      setShow(true)
    })
    element.addEventListener('mouseleave', () => {
      setShow(false)
    })
  }, [])

  const copyText = () => {
    navigator.clipboard
      .writeText(path)
      .then(() => message.success('复制地址成功'))
      .catch(() => message.error('复制地址失败'))
  }

  // 下载文件
  const downFile = () => (window as any).fileControl.downFile(path)

  // 删除图片
  const deleteImage = async () => {
    const res = await deleteImageApi(id)
    if (res.code !== 200) return message.error('删除失败！')
    message.success('删除成功！')
    refreshList()
  }

  return (
    <div className={styles.imageItem} ref={myElementRef}>
      <Image width={90} src={path} />

      <div className={styles.serial}>{serial + 1}</div>

      {show ? (
        <div className={styles.btn}>
          <DownloadOutlined title="下载图片" onClick={downFile} />
          <HistoryOutlined title={`上传时间：${time}`} />
          <CopyOutlined title="复制图片地址" onClick={copyText} />
        </div>
      ) : (
        <div className={styles.btn}></div>
      )}

      {show ? (
        <DeleteFilled
          className={styles.deleteBtn}
          title="删除"
          onClick={deleteImage}
        />
      ) : (
        ''
      )}
    </div>
  )
}
